WingStudio第三轮项目途中报错及解决方案
请遵循一步一测试的原则,否则后续定位错误极其麻烦!!!
一、sql 驱动连接不上,抛出 ClassNotFoundException
解决方案:
检查 sql驱动版本与所装 sql 版本是否一致。
二、 MyBatis 加载全局配置文件时出错
解决方案:
全局配置文件的路径应使用 com/tinysnow/easyvote/conf/xml/mybatis-config.xml
这种斜杠方式而非 . 的方式。
三、 MyBatis 不能加载 properties 配置文件
报错如下: Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource mysql-connection.properties
解决方案:
应使用全局的路径 com/tinysnow/easyvote/conf/mysql-connection.properties
结果正确。
四、 MyBatis 不能加载 Mappers 中的 spl 映射配置文件
解决方案:
路径错了,以及没有使用 / 表示法,而使用 . 的表示法。
五、 绑定数据库两个异常的解决办法
第一个:Type interface **************************** is not known to the MapperRegistry.
译文:MapperRegistry不知道类型接口com.tinysnow.easyvote.dao.intrfc.JdbcMethods。
第二个:Invalid bound statement (not found): ***********************.
译文:无效的绑定语句(未找到):com.tinysnow.easyvote.dao.intrfc.JdbcMethods.insertUser。
解决方案:
映射文件里面的 namespace 路径应该用 . 号,而非 / 或 \ ,路径的最后也不要带上文件后缀名,否则将认为文件后缀名所带的 . 号认为是下一个目标路径。并且在配置诸如 等的标签的时候,里面不要配置 databaseId 。 虽说不清楚啥原理,但这么改就好了。
六、关于使用 Maven 管理依赖中 Mybatis 报错问题
引入 properties 文件后在测试方法中测试最基础的 Mybatis 启动报错,两个异常如下:
Cause: java.lang.NullPointerException
at MyBatisStartTest.main(MyBatisStartTest.java:14)
java.io.IOException: Could not find resource /mybatis-config.xml
at MyBatisStartTest.main(MyBatisStartTest.java:14)
解决方案:
- 资源文件统一扔在 resources 目录下面;
- 测试方法中的路径字符串
String resource = "mybatis-config.xml";
路径一定要正确,最保险的方法是使用 IDEA 的 copy -> path from source root ; - 最重要的,报 NullPointerException 的原因是 mybatis-config.xml 文件中没有配置 environment 标签,一定要加上如下的代码,否则找死找不到,连接不到数据库。里面的数据库驱动标签什么的按实际情况配置。
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
另,数据库驱动是使用 properties 标签引进来的。
<properties resource="database.properties">
</properties>
七、关于在 try 块中定义资源导致无法编译的问题
解决方案:
- 进入 idea -> File -> Settings -> Build, Execution, Deployment -> Compiler -> Java Compiler -> 选择项目旁边的 Target bytecode version -> 改成8
- 进入 idea -> File -> Project Structure -> Modules -> Language Level -> 改成 Project default
八、注意:数据库连接问题,有坑
连接上数据库是没有指定数据库名的,所以在写 sql 语句的时候需要先指定数据库名,然后是表名,用句点连接。比如: select * from user.userinfo where id = #{id}
九、关于 MyBatis 中 Mapper 文件中 sql 语句执行正确不报异常,但是数据表中看不见执行结果的现象
解决方案:
在编写的测试方法里面 SqlSession session = build.openSession()
session 更新完 sql 是不自动提交的,一定要切记。需要加上如下语句:
session.commit();
十、关于 SpringBoot 启动时的报错
报错如下:
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
Action:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).
解决方案:
在 application.yml / application.properties 中添加数据库的相关设置:
spring:
datasource:
username: root
password: tinysnow;
url: jdbc:mysql://localhost:3306/?useUnicode=true
&characterEncoding=utf-8&allowPublicKeyRetrieval=true&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
特别注意: url 下面第二行前面的空格一定不能省略。
十一、关于 MyBatis 在 SpringBoot 中找不到绑定文件的错误
新建了一个 application-mybatis.yml 配置文件如下:(配置文件的文件名一定要是 application- .yml的形式)
mybatis:
mapper-locations: classpath:mybatis/mappers/*.xml
type-aliases-package: com.tinysnow.bean
然后一定不要忘记去主 application.yml 配置文件中激活!
spring:
profiles:
active: druid,mybatis
# 激活时只用写 application- 后面的单词
十二、 SpringBoot 启动时报错
异常如下:
java.lang.IllegalStateException: dbType not support : null, url null
解决方案,在 druid 配置文件中的 prefix 后缀中去掉 druid ,只保留 spring.datasource 。启动正常。
- druid 配置文件与 spring 配置文件的双向绑定:
@Configuration
public class DruidConfig {
@ConfigurationProperties(prefix = "spring.datasource")
@Bean
public DataSource druidDataSource(){
return new DruidDataSource();
}
@Bean
public ServletRegistrationBean servletRegistrationBean(){
final ServletRegistrationBean bean =
new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
// 后台需要有人登录,配置账号和密码
final HashMap hashMap = new HashMap();
// 增加配置
hashMap.put("loginUsername","admin");
hashMap.put("loginPassword","123456");
// 允许谁可以访问, Value 不写就默认所有主机都可以访问
hashMap.put("allow","");
// 还可以禁止谁能访问,此时的 Key 就是自定义的, Value 指定 ip 地址
// 例如 hashMap.put("tinysnow","192.168.3.7");
// 设置初始化参数
bean.setInitParameters(hashMap);
return bean;
}
}
注意:这些注解一个都不能少
十三、关于每次启动项目总是跳出登陆页面的问题
如下图所示:
解决方案:这是 SpringSecurity 的特性,登录的用户名默认是 user ,密码默认是控制台输出的一大串字符,也可以自己设置,凡是具体设置流程暂未关心。
十四、关于 MyBatis 查询返回结果过多的问题
异常:
TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: *
解决方案:
将接口中的返回值类型改为 List 即可。
十五、关于 MyBatis 查询结果为 null 的问题
解决方案:
实体类(pojo, bean, modal...)中的字段名一定要与数据库中的一一对应,否则查询不出结果。现有松耦合的方法可以使数据库中的名字不与实体类中的一一对应。通过以下方式开启:
mybatis:
configuration:
# 自动开启数据库下划线命名 与 实体类中驼峰命名法的匹配
# 以达到双方命名均规范的目的
map-underscore-to-camel-case: true
十六、关于 git 各种命令都无效的问题
解决方案:
看看自己是在哪个目录下进行操作的,千万不要 cd 错了目录。
十七、关于修改 IDEA 中数据表的各项属性不能成功的问题
解决方案:
在右侧栏 Database 中选中数据表右键 Modify Table 或者按下 Ctrl+F6 在该栏里面修改数据表才算成功。选中数据表点击最上面的笔,修改代码的结果是不能提交的,也就自然不能成功了。
十八、关于新建项目 Maven 导入慢的问题
解决方案:
在 C: \ Users \ [user] \ .m2 下建立一个文件 settings.xml 将下述代码拷贝进去。或者在 IDEA 的 Project 空白栏右键选择 Maven 然后创建 settings 。
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<mirrors>
<!-- mirror
| Specifies a repository mirror site to use instead of a given repository. The repository that
| this mirror serves has an ID that matches the mirrorOf element of this mirror. IDs are used
| for inheritance and direct lookup purposes, and must be unique across the set of mirrors.
|
<mirror>
<id>mirrorId</id>
<mirrorOf>repositoryId</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://my.repository.com/repo/path</url>
</mirror>
-->
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
<mirror>
<id>uk</id>
<mirrorOf>central</mirrorOf>
<name>Human Readable Name for this Mirror.</name>
<url>http://uk.maven.org/maven2/</url>
</mirror>
<mirror>
<id>CN</id>
<name>OSChina Central</name>
<url>http://maven.oschina.net/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
<mirror>
<id>nexus</id>
<name>internal nexus repository</name>
<!-- <url>http://192.168.1.100:8081/nexus/content/groups/public/</url>-->
<url>http://repo.maven.apache.org/maven2</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
</settings>
十九、 关于工程文件夹默认路径的修改
Settings > Appearance & Behavior > System Settings > Project > Default project directory .
二十、关于新建项目启动后报错 404 的问题
解决方案:
其实是没有设置默认页面的问题,可以加一个 Controller 和页面,后面发现其实是正常的。可以加如下代码,记得加上 @ResponseBody ,否则还是报错。
package com.tinysnow.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @author TinySnow
*/
@Controller
public class TestController {
@RequestMapping("/")
@ResponseBody
public String test(){
return "HelloWorld";
}
}
然后在 templates 目录下新建一个 HelloWorld.html 后,重新启动项目,发现是正常的。
二十一、关于建立单元测试爆空指针异常的问题
解决方案:
是因为此时的 candidateMapper 并没有被 Spring 托管,左侧都没有出现叶子的图标。在类上加上 @SpringBootTest。
二十二、 关于对 Mybatis 中 Mapper 进行单元测试的报错问题
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method setCandidateMapper in com.tinysnow.dao.impl.CandidateDaoImpl required a bean of type 'com.tinysnow.mappers.CandidateMapper' that could not be found.
Action:
Consider defining a bean of type 'com.tinysnow.mappers.CandidateMapper' in your configuration.
解决方案:
是因为这个 com.tinysnow.mappers.CandidateMapper 压根儿就没找到。
在主启动类上添加 @MapperScan("com.tinysnow.mappers") 注解,或者在每一个 Mapper 接口上定义 @Mapper 注解。这样才能被 MyBatis 找到。
二十三、关于没有找到文件的问题
报错信息:
F:\Projects\Java\Wing\src\test\java\com\tinysnow\mappers\JudgeMapperTest.java:11:5
java: 找不到符号
符号: 类 JudgeMapper
位置: 类 com.tinysnow.mappers.JudgeMapperTest
解决方案:
这个可能是由于 IDEA 抽疯,没有自动编译,直接复制文件就有可能出现这个问题。点击模块,右键,rebuild 一下就可以了。
二十四、关于 git 拉不下来代码的问题
拒绝拉代码的提示性语句: refusing to merge unrelated histories
翻译:拒绝合并无关的历史
解决方案:
如果合并了两个不同的开始提交的仓库,在新的 git 会发现这两个仓库可能不是同一个,为了防止开发者上传错误,于是就给下面的提示
fatal: refusing to merge unrelated histories
如我在Github新建一个仓库,写了License,然后把本地一个写了很久仓库上传。这时会发现 github 的仓库和本地的没有一个共同的 commit 所以 git 不让提交,认为是写错了 origin
,如果开发者确定是这个 origin
就可以使用 --allow-unrelated-histories
告诉 git 自己确定
遇到无法提交的问题,一般先pull 也就是使用 git pull origin master
这里的 origin
就是仓库,而 master
就是需要上传的分支,因为两个仓库不同,发现 git 输出 refusing to merge unrelated histories
无法 pull 内容
因为他们是两个不同的项目,要把两个不同的项目合并,git需要添加一句代码,在 git pull
之后,这句代码是在git 2.9.2版本发生的,最新的版本需要添加 --allow-unrelated-histories
告诉 git 允许不相关历史合并
假如我们的源是origin,分支是master,那么我们需要这样写git pull origin master --allow-unrelated-histories
如果有设置了默认上传分支就可以用下面代码
git pull --allow-unrelated-histories
参考链接:
https://blog.csdn.net/lindexi_gd/article/details/52554159
二十五、关于 git 更改提交代码的邮箱
查看本机用户下.gitconfig这个文件,打开之后查看对应的 name 和 email 是否和自己想要设置的一致,如果不一致,打开git bash :
git config --global user.name "设置自己的名字"
git config --global user.email "设置自己的邮箱"
这两条指令设置。idea 也中 git commit时有这一框可以选择。
参考链接:
https://blog.csdn.net/weixin_42257062/article/details/80509641
二十六、git 合并分支
切换回主分支,然后
git merge [想要合并的分支名字]
注意:此命令只会合并分支上的文件到 master 分支,但不会删除分支。
二十七、Vue 主页进不去
解决方案:
const routes = [
{ path: '/', redirect: '/login' },
{ path: '/login', components: LoginAndRegister },
{ path: '/create', component: CreateProject },
{ path: '/manage', component: ManageProject },
{ path: '/result', component: ShowResult}
]
components 改为 component
二十八、关于通过 Vuex 的 mutations 提交修改不起作用的问题
解决方案:
在自己的 mutations 业务代码里修改 state 里的属性时,引用是 this.state.[property]
而不是 this.[property]
在全局调用 mutation 的函数时不需要传入 state 相关的参数,因为这是一个内部的引用,只需要传入 username 就可以,如:
this.$store.commit("changeUserLoginState", "114514")
二十九、MyBatis数组参数传入报错
报错信息:
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:
### Error updating database. Cause: java.lang.UnsupportedOperationException
### The error may exist in file [F:\Projects\Java\Wing\target\classes\mybatis\mappers\CandidateMapper.xml]
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: insert into candidates (project_id, candidate_name, describe_msg, vote_number) values (?,?,?,0);
### Cause: java.lang.UnsupportedOperationException
报错代码:
<insert id="insertCandidate" useGeneratedKeys="true">
insert into candidates (project_id, candidate_name, describe_msg, vote_number)
values (#{list.projectId},#{list.candidateName},#{list.describeMsg},0);
</insert>
解决方案:
因为是数组形式插入的,所以这种写法是不对的,还要在 xml 文件中进行循环遍历取值才能够批量插入。代码如下:
<insert id="insertCandidate" useGeneratedKeys="true">
insert into candidates (project_id, candidate_name, describe_msg, vote_number) values
<foreach item="list" collection="list" separator=",">
(#{list.projectId},#{list.candidateName},#{list.describeMsg},0)
</foreach>;
</insert>
/* item 里面填入 Mapper 文件传过来的 list 参数, collection 则为集合的类型, set,list 之类的*/
/* separator 填入分隔符,需要符合 mysql 的语法规范,最后循环出来结果如下: */
/* insert into candidates (project_id, candidate_name, describe_msg, vote_number)
values (XXX,XXX,XXX,0),(XXX,XXX,XXX,0),(XXX,XXX,XXX,0),(XXX,XXX,XXX,0) */
三十、关于发出的请求总是404的问题
解决方案:
一定要检查自己发出请求的时候,是不是完整的后台代码路径。后台代码里类上的路径很容易被忽略!
三十一、关于在页面上进行增删改查后刷新数据表的方法
参考链接:https://juejin.im/entry/6844903798620553224
采用的方法3
<template>
<div id="app">
<router-view v-if="isRouterAlive"></router-view>
</div>
</template>
<script>
export default {
name: "app",
provide () {
return {
reload: this.reload
}
},
data () {
return {
isRouterAlive: true
}
},
methods: {
reload () {
this.isRouterAlive = false
this.$nextTick(() => this.isRouterAlive = true)
}
}
}
</script>
<style>
</style>
依据代码解析,大概应该是如果当前路由被激活(事实上是一定激活的,不然不可能看得到页面,也就是说,看到页面的时候 isRouterAlive 是一定为 true 的),然后将其赋值为 false 使页面短暂不可见,然后随即又赋值为 true ,期间 Vue 的组件被创建和销毁,以达到刷新的目的。但是 this.$nextTick 这个方法是个什么东西暂时不知道。
三十二、关于前端页面数据表格中点击编辑,数据传不到对话框中内嵌表单的输入框默认值的问题
解决方案:
有一个非常邪道的方法,点击编辑的时候会绑定一个事件,将所有的数据传入到此事件中,然后赋给表单的数据项中,再在对话框里采用表单的数据项就可以了。
不能在 data 中直接赋值 table 里面的数据,因为 table 里面的每一项是不一样的,动态的,会变的,其中 Element-UI 更是有一个叫 index 和 row 的东西,直接限制了这种做法。代码如下:
export default {
inject: ['reload'],
name: "ShowJudges",
data() {
return {
tableData: [{
judgeId: '',
judgeName: '',
judgePwd: '',
projectId: '',
hasVoted: ''
}],
dialogFormVisible: false,
form: {
judgeName: '',
judgePwd: '',
hasVoted: ''
},
formLabelWidth: '120px'
}
},
methods: {
handleEdit(index, row, boolean) {
this.dialogFormVisible = boolean
this.form.judgeName = row.judgeName
this.form.judgePwd = row.judgePwd
this.form.hasVoted = row.hasVoted
console.log(this.form.hasVoted);
}
三十三、关于 Radio 中不能根据数据项自动默认选中选项的问题
<el-form-item label="投票权" :label-width="formLabelWidth">
<el-radio v-model="form.hasVoted" label="false">有</el-radio>
<el-radio v-model="form.hasVoted" label="true">无</el-radio>
</el-form-item>
<!--这里仅展示有关的代码段-->
form: {
judgeName: '',
judgePwd: '',
hasVoted: ''
}
handleEdit(index, row, boolean) {
this.dialogFormVisible = boolean
this.form.judgeName = row.judgeName
this.form.judgePwd = row.judgePwd
this.form.hasVoted = row.hasVoted
},
解决方案:
记住,= 后面如果没有使用 v-bind 绑定属性,那么系统默认就是使用字符串!哪怕是 false 或者 true 这种东西,也只会当成字符串处理。所以一定要记得加上 v-bind !
在两个 label 前面加上 : 即可。
三十四、关于使用 fastjson 时,其自动过滤掉值为 null 的字段名的问题
如题,如果想要其转成 JSON 时仍然保留值为 null 的字段,需要在 toJSONString(param1, param2) 的 param2 中添加一个配置: SerializerFeature.WriteMapNullValue 。示例如下:
return JSON.toJSONString(judge, SerializerFeature.WriteMapNullValue)
这样既可保留值为 null 的字段。
参考链接:
https://blog.csdn.net/SongSir001/article/details/84656579?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.channel_param
三十五、 关于 POST 请求爆 403 Forbidden 的问题
这个问题困扰了我很久,最后请求哥哥帮助才解决。
是 Spring Security 的问题, Security 在有客户端发起请求的时候会将这些请求先过滤一遍,如果遇到有不合理的请求(可能是没有经过授权或者其他什么原因,目前尚不清楚),会直接进行拦截,如发一个 403 打回去,后台根本拿不到这个请求进行处理。
解决方案:
注释 Spring Security 。当然这是最为极端的方法,可以在 Security 中添加白名单从而使 Security 通过这些请求。但是目前没有时间去了解怎样进行操作,暂时先注释掉了。以上情况只针对于前端和后端已经进行了跨域处理的情况,如果未进行跨域处理,则还会爆出其他异常情况。
三十六、关于 @RequestBody , JSON 数组转为 Java 对象 List ,以及连带的 Converter 和泛型擦除问题
@RequestBody 是 SpringBoot 中自带的一个将 JSON 转化为 Java 对象的一个注解,也就是说,当在 Controller 层的接收参数前加上 @RequestBody 时,这个参数在 SpringBoot 内部就已经由 JSON 转化为了 Java 对象,因此这个注解修饰的对象应该是,包含与 JSON 传过来的字段名相对应的后台实体类对象,所以不需要再进行 JSON 转对象处理。
而这个注解有些对象是不能进行自动转化的,比较特殊。不能进行自动转化的条件:
- 包含泛型
- 实体类中含有 Date 诸如此类的必须使用的字段
因为 JSON 数组转为 Java 对象 List 这个调用中,本身 List 是含有泛型的,所以需要实现一个接口,即 Converter ,以自己手动进行 JSON 转对象的正确处理,代码如下:
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.databind.util.Converter;
import com.tinysnow.bean.Candidate;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author TinySnow
*/
@Component
public class String2CandidateListConverter implements Converter {
@Override
public List convert(String s) {
return JSON.parseArray(s, Candidate.class);
}
@Override
public JavaType getInputType(TypeFactory typeFactory) {
return null;
}
@Override
public JavaType getOutputType(TypeFactory typeFactory) {
return null;
}
}
后两个方法可以不要。这是 JSON 数组转为 Java 对象 List 最为正规和规范的写法。
之所以不能包含泛型,是因为 Java 在设计之初的泛型擦除机制,即在源码阶段指定的泛型,在编译出来的字节码中被擦除了,不知道这个泛型到底是什么。而不能包含 Date 类型,是因为 Date 在转化时需要经过计算和格式确定。
注意: Converter 转化成对象时,这个对象的实体类里不能有基础类型,即 int, boolean 等,需要用其对应的包装对象 Integer, Boolean 等。
三十七、关于发起请求时参数传递的形式
搞清楚: x-www-form-urlencoded 的参数传递形式是 Key=Value&Key=Value...
所以在传递到后台时会报错,错误码是 415 :不支持的媒体类型 (Unsupported media type) 。
而传递到后台的参数形式应该为 JSON 形式,所以需要在请求时修改请求头 Content-Type 为 application/json 。
示例:
axios.post("http://localhost:8088/judge/update", data1, {
headers: { 'Content-Type': 'application/json'}
}).then(resp => {}).catch(err => {})
其他知识
- 将两行合并为一行并移除多余空格,可以使用 Ctrl + Shift + J ;